package com.mjk.common.core.health;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mjk.common.tools.gson.GsonUtils;
import com.mjk.common.util.ComputerUtils;
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
import org.springframework.boot.actuate.health.Health;
import org.springframework.stereotype.Component;

import java.io.File;
import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * 系统使用 健康检测
 * 1 运行硬盘 > 100M
 * 2 CPU使用率 < 85%
 * 3 内存使用率 < 85%
 */
@Component
public class SystemUsageHealthIndicator extends AbstractHealthIndicator {
    private static final float DISK_SPACE = 1*1024*1024*1024f; //硬盘剩余 小于1G
    private static final float CPU_USAGE = 0.7f;//cpu使用率大于70%

    private static final float HEAD_USAGE = 200*1024*1024f;//堆内存剩余小于200M

    private static final float PHYSICAL_USAGE = 1*1024*1024*1024f;//物理内存小于1G
    protected void doHealthCheck(Health.Builder builder) throws Exception {
        boolean isHealth = isSpaceHealth(builder);
        if(isHealth){
            builder.up();
        }else{
            builder.down();
        }
    }

    private boolean isSpaceHealth(Health.Builder builder){
        ComputerUtils.ComputerInfo info = ComputerUtils.getComputerInfo();
        builder.withDetail("硬盘剩余",ComputerUtils.formatSize(info.getDiskSpace()));
        builder.withDetail("cpu使用",String.format("%.2f%%",info.getSystemLoadAverage() * 100));
        builder.withDetail("堆空间(空闲/总共)",ComputerUtils.formatSize(info.getFreeHeadMemory()) +"/"+ ComputerUtils.formatSize(info.getTotalHeadMemory()));
        builder.withDetail("物理内存(空闲/总共)",ComputerUtils.formatSize(info.getFreePhysicalMemory())+"/"+ComputerUtils.formatSize(info.getTotalPhysicalMemory()));
        if(info.getDiskSpace() < DISK_SPACE){
            builder.withDetail("硬盘","磁盘剩余小于"+ComputerUtils.formatSize(DISK_SPACE)); //小于1G
            return false;
        }
        if(info.getSystemLoadAverage() > 0.7){
            builder.withDetail("cpu","使用率大于70%"); //大于70%
            return false;
        }
        if(info.getFreeHeadMemory() < HEAD_USAGE){
            builder.withDetail("堆空间","小于"+ComputerUtils.formatSize(HEAD_USAGE)); //小于200M
            return false;
        }
        if(info.getFreePhysicalMemory() < PHYSICAL_USAGE){
            builder.withException(new Throwable("物理内存小于"+ComputerUtils.formatSize(PHYSICAL_USAGE))); //小于1G
            return false;
        }
        return true;
    }

    private String formatSize(long size){
        String[] units = {"B","KB","MB","GB","TB"};
        int index =0;
        double formateSize = size;
        while(formateSize>=1024 && index<units.length-1){
            formateSize/=1024;
            index++;
        }
        return String.format("%.2f %s",formateSize,units[index]);
    }


    public static double twoDecimal(double doubleValue) {
        BigDecimal bigDecimal = new BigDecimal(doubleValue).setScale(2, RoundingMode.HALF_UP);
        return bigDecimal.doubleValue();
    }

}
